package co.gov.medellin.sdep.sisdep.domain;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;

import co.gov.medellin.sdep.sisdep.common.dto.GenericComponentVO;
import co.gov.medellin.sdep.sisdep.common.dto.GenericComponentValueVO;
import co.gov.medellin.sdep.sisdep.common.AppConstants;

/**
 * Controlador para el manejo de los CRUD de Listas Maestras de Tipo y Valor Tipo
 * @author carlos.perez@consult-soft.com
 * @version 08/02/2012
 */
public class MasterListController  extends BaseController implements java.io.Serializable {
	
	/** Serial key. */
	private static final long serialVersionUID = -118871763606900426L;

	/** Instancia de SessionControler para el manejo de objetos en session. */
	/*
	 * Al revisar la jerarquia de controladores nos damos cuenta que este
	 * controlador es un intermiediario para establecer o tomar valores del
	 * ambito de session.
	 * Este controlador sessionController hereda del mismo padre BaseController
	 * y tiene igual acceso al metodo Map getSessionMap(), que se encuentra en
	 * el FacesController. Este objeto realmente sobra.
	 * Se debe reutilizar las funcionalidades expuestas en la clase padre
	 * ya no se requiere un intermiediario ya que la funcionalidad esta 
	 * heredada.
	 */
	//public static SessionController sessionController = new SessionController();

	/** Value Object para el manejo del formulario de busqueda de Tipos. */
	private GenericComponentVO typeSearchVO;
	
	/** Objeto contenedor del listado de Tipos luego de una consulta. */
	private transient DataModel typeVOListModel;

	/** Value Object para el manejo del formulario de creacion/edicion de Tipos. */
	private GenericComponentVO typeAdmonVO;
	
	/** Value Object para el manejo del formulario de busqueda de Valores Tipo. */
	private GenericComponentValueVO typeValueSearchVO;
	
	/** Objeto contenedor del listado de Tipos/ValorTipo luego de una consulta. */
	private transient DataModel typeValueVOListModel;

	/** Value Object para el manejo del formulario de creacion/edicion de Valores Tipo. */
	private GenericComponentValueVO typeValueAdmonVO;

	/** Lista de Tipos para las listas maestras */
	private List typeMasterList;

	/** DAO ValueObject */
	private co.gov.medellin.sdep.sisdep.admin.service.IValueObjectService valueObjectService;
	
	/**
	 * Constructor por defecto, inicializa los elemento basicos del Controlador
	 */
	public MasterListController() {
		this.typeVOListModel = new ListDataModel();
		this.typeValueVOListModel = new ListDataModel();
	}

	/**
	 * @return the typeSearchVO
	 */
	public GenericComponentVO getTypeSearchVO() {
		if (this.typeSearchVO == null) {
			this.typeSearchVO = new GenericComponentVO(false);
		}
		return typeSearchVO;
	}

	/**
	 * @param typeSearchVO the typeSearchVO to set
	 */
	public void setTypeSearchVO(GenericComponentVO typeSearchVO) {
		this.typeSearchVO = typeSearchVO;
	}

	/**
	 * @return the typeVOListModel
	 */
	public DataModel getTypeVOListModel() {
		return typeVOListModel;
	}

	/**
	 * @param typeVOListModel the typeVOListModel to set
	 */
	public void setTypeVOListModel(DataModel typeVOListModel) {
		this.typeVOListModel = typeVOListModel;
	}
	
	//--------------------------------------------------------------------
	//--- metodos para atender acciones 							init()
	//--------------------------------------------------------------------
	
	/**
	 * Metodo que permite obtener el listado de Tipos para ser usados en administracion de los mismos.
	 * @author carlos.perez@consult-soft.com  03-02-2012
	 * @return String
	 */
	public String searchTypeByKey() {
		try {
			this.typeVOListModel.setWrappedData(getValueObjectService().loadTypeMasterList((this.typeSearchVO)));
		}  catch (Exception e) {
			// REGISTRAR EN EL LOG Y REDIRECCIONAR A PAGINA DE ERROR - POR DEFINIR
			e.printStackTrace(System.err);
		}
		//NOTA DESDE LOS DAOS cuando no hay valores se retorna un null
		//por esto esta condicion debe cambiar y anteponer un if de revision
		//de valor en null
		if(this.typeVOListModel.getWrappedData() == null){
			((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
            .setSuccessMessage("- NO se obtuvieron registros para el Tipo de Lista Maestra especificado !!", null, null);
		}else{
			if(((List)this.typeVOListModel.getWrappedData()).isEmpty()) {
				((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
	            .setSuccessMessage("- NO se obtuvieron registros para el Tipo de Lista Maestra especificado !!", null, null);
			}
		}
		return AppConstants.OPTION_SEARCH_TYPE_ADMON;
	}	
	
	/**
	 * Metodo que permite espeficicar la funcionalidad para la operacion Editar un Tipo de Lista Maestra 
	 * @author carlos.perez@consult-soft.com  03-02-2012
	 * @return String
	 */
	public String editType() {
		 Map params =  getExternalContext().getRequestParameterMap();
         String typeDataIndex = (String)params.get("typeDataIndex");
         this.typeAdmonVO = (GenericComponentVO)((List)this.typeVOListModel.getWrappedData()).get(Integer.parseInt(typeDataIndex));
         
		 return AppConstants.OPTION_EDIT_TYPE_ADMON;
	}

	/**
	 * @return the typeAdmonVO
	 */
	public GenericComponentVO getTypeAdmonVO() {
		return typeAdmonVO;
	}

	/**
	 * @param typeAdmonVO the typeAdmonVO to set
	 */
	public void setTypeAdmonVO(GenericComponentVO typeAdmonVO) {
		this.typeAdmonVO = typeAdmonVO;
	}

	/**
	 * Metodo que permite espeficicar la funcionalidad para la operacion Crear / Actualizar un Tipo de Lista Maestra 
	 * @author carlos.perez@consult-soft.com  06-02-2012
	 * @return String
	 */
	public String manageType() {
		String manageTypeMsg = "ERROR de Ejecucion del Sistema !!";
		try {
			this.typeAdmonVO.setLoggedUserId(getLoggedUserID());
			if(this.typeAdmonVO.getComponentId().equals("")) {
				getValueObjectService().saveTypeMasterList(this.typeAdmonVO);
				manageTypeMsg = "creado EXITOSAMENTE !! ";
			} else {
				getValueObjectService().updateTypeMasterList(this.typeAdmonVO);
				manageTypeMsg = "actualizado EXITOSAMENTE !! ";
			}
			// Se anula la lista de Tipos, para que sea actualizada con el nuevo elemento desde la base de datos:
			getTypeMasterList().clear();
			this.typeMasterList = null;

		}  catch (Exception e) {
			// TODO Auto-generated catch block
			// REGISTRAR EN EL LOG Y REDIRECCIONAR A PAGINA DE ERROR - POR DEFINIR
			e.printStackTrace(System.err);
		}				
		((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
		                                .setSuccessMessage("- Tipo Maestra " + manageTypeMsg, null, null);
		 
		return AppConstants.OPTION_SEARCH_TYPE_ADMON;
	}
	

	/**
	 * Metodo que permite inicalizar el objeto VO para la operacion Crear un Tipo de Lista Maestra 
	 * @author carlos.perez@consult-soft.com  06-02-2012
	 * @return String
	 */
	public String newType() {
         this.typeAdmonVO = new GenericComponentVO(false);
    	 this.typeAdmonVO.setComponentId("");
    	 this.typeAdmonVO.setComponentKey("");
    	 this.typeAdmonVO.setComponentDescription("");         
		 return AppConstants.OPTION_EDIT_TYPE_ADMON;
	}
	
	/**
	 * Metodo que permite cancelar una operacion de Crear / Actualizar un Tipo de Lista Maestra 
	 * @author carlos.perez@consult-soft.com  06-02-2012
	 * @return String
	 */
	public String cancelManageType() {
		return AppConstants.OPTION_SEARCH_TYPE_ADMON;
	}

	/**
	 * @return the typeMasterList
	 */
	public List getTypeMasterList() {
		if(null == typeMasterList) {
		    // Se inicializa la lista de tipos para las listas maestras:
			try {
				String tmpKey = getTypeSearchVO().getComponentKey();
				getTypeSearchVO().setComponentKey("%");
				this.typeMasterList = new ArrayList(0);
				Iterator typeMasterIterator = getValueObjectService().loadTypeMasterList(getTypeSearchVO()).iterator();
				
			    while (typeMasterIterator.hasNext()) {
			    	GenericComponentVO gcVO = (GenericComponentVO) typeMasterIterator.next();		 
			    	this.typeMasterList.add(new SelectItem(gcVO.getComponentId(), gcVO.getComponentKey()));
			    }
				getTypeSearchVO().setComponentKey(tmpKey);
			}  catch (Exception e) {
				// TODO Auto-generated catch block
				// REGISTRAR EN EL LOG Y REDIRECCIONAR A PAGINA DE ERROR - POR DEFINIR
				e.printStackTrace(System.err);
			}
		}
		return typeMasterList;
	}

	/**
	 * @param typeMasterList the typeMasterList to set
	 */
	public void setTypeMasterList(List typeMasterList) {
		this.typeMasterList = typeMasterList;
	}
	
	/**
	 * Metodo que permite obtener el listado de Valores para Tipos a ser usados en administracion de los mismos.
	 * @author carlos.perez@consult-soft.com  07-02-2012
	 * @return String
	 */
	public String searchTypeValueByParams() {
		try {
			this.typeValueVOListModel.setWrappedData(getValueObjectService().loadTypeValueMasterList((this.typeValueSearchVO)));
		}  catch (Exception e) {
			// TODO Auto-generated catch block
			// REGISTRAR EN EL LOG Y REDIRECCIONAR A PAGINA DE ERROR - POR DEFINIR
			e.printStackTrace(System.err);
		}
		if(this.typeValueVOListModel.getWrappedData() == null){
			((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
            .setSuccessMessage("- NO se obtuvieron registros de Valores Tipo para la consulta especificada !!", null, null);
		}else{
			if(((List)this.typeValueVOListModel.getWrappedData()).isEmpty()) {
				((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
		                                        .setSuccessMessage("- NO se obtuvieron registros de Valores Tipo para la consulta especificada !!", null, null);
			}
		}
		return AppConstants.OPTION_SEARCH_TYPE_VALUE_ADMON;
	}	
	
	/**
	 * Metodo que permite espeficicar la funcionalidad para la operacion Editar un Valor Tipo de Lista Maestra 
	 * @author carlos.perez@consult-soft.com  07-02-2012
	 * @return String
	 */
	public String editTypeValue() {
		 Map params =  getExternalContext().getRequestParameterMap();
         String typeValueDataIndex = (String)params.get("typeValueDataIndex");
         this.typeValueAdmonVO = (GenericComponentValueVO)((List)this.typeValueVOListModel.getWrappedData()).get(Integer.parseInt(typeValueDataIndex));
         
		 return AppConstants.OPTION_EDIT_TYPE_VALUE_ADMON;
	}


	/**
	 * Metodo que permite espeficicar la funcionalidad para la operacion Crear / Actualizar un Valor Tipo de Lista Maestra 
	 * @author carlos.perez@consult-soft.com  07-02-2012
	 * @return String
	 */
	public String manageTypeValue() {
		String manageTypeValueMsg = "ERROR de Ejecucion del Sistema !!";
		try {
			this.typeValueAdmonVO.setLoggedUserId(getLoggedUserID());
			if(this.typeValueAdmonVO.getComponentValueId().equals("")) {
				getValueObjectService().saveTypeValueMasterList(this.typeValueAdmonVO);
				manageTypeValueMsg = "creado EXITOSAMENTE !! ";
			} else {
				getValueObjectService().updateTypeValueMasterList(this.typeValueAdmonVO);
				manageTypeValueMsg = "actualizado EXITOSAMENTE !! ";
			}
		}  catch (Exception e) {
			// TODO Auto-generated catch block
			// REGISTRAR EN EL LOG Y REDIRECCIONAR A PAGINA DE ERROR - POR DEFINIR
			e.printStackTrace(System.err);
		}				
		((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
		                                .setSuccessMessage("- Valor Tipo Maestra " + manageTypeValueMsg, null, null);
		 
		return AppConstants.OPTION_SEARCH_TYPE_VALUE_ADMON;
	}

	/**
	 * Metodo que permite inicalizar el objeto VO para la operacion Crear un Valor Tipo de Lista Maestra 
	 * @author carlos.perez@consult-soft.com  07-02-2012
	 * @return String
	 */
	public String newTypeValue() {
         typeValueAdmonVO = new GenericComponentValueVO();
    	 typeValueAdmonVO.setComponentId("");
    	 typeValueAdmonVO.setComponentValueId("");
    	 typeValueAdmonVO.setComponentValueName("");
    	 typeValueAdmonVO.setComponentValueKey("");
    	 typeValueAdmonVO.setComponentValueDesc("");
         
		 return AppConstants.OPTION_EDIT_TYPE_VALUE_ADMON;
	}

	/**
	 * Metodo que permite cancelar una operacion de Crear / Actualizar un Valor Tipo de Lista Maestra 
	 * @author carlos.perez@consult-soft.com  07-02-2012
	 * @return String
	 */
	public String cancelManageTypeValue() {
		return AppConstants.OPTION_SEARCH_TYPE_VALUE_ADMON;
	}

	/**
	 * @return the typeValueSearchVO
	 */
	public GenericComponentValueVO getTypeValueSearchVO() {
		if (this.typeValueSearchVO == null) {
			this.typeValueSearchVO = new GenericComponentValueVO();
		}
		return typeValueSearchVO;
	}

	/**
	 * @param typeValueSearchVO the typeValueSearchVO to set
	 */
	public void setTypeValueSearchVO(GenericComponentValueVO typeValueSearchVO) {
		this.typeValueSearchVO = typeValueSearchVO;
	}

	/**
	 * @return the typeValueAdmonVO
	 */
	public GenericComponentValueVO getTypeValueAdmonVO() {
		return typeValueAdmonVO;
	}

	/**
	 * @param typeValueAdmonVO the typeValueAdmonVO to set
	 */
	public void setTypeValueAdmonVO(GenericComponentValueVO typeValueAdmonVO) {
		this.typeValueAdmonVO = typeValueAdmonVO;
	}

	/**
	 * @return the typeValueVOListModel
	 */
	public DataModel getTypeValueVOListModel() {
		return typeValueVOListModel;
	}

	/**
	 * @param typeValueVOListModel the typeValueVOListModel to set
	 */
	public void setTypeValueVOListModel(DataModel typeValueVOListModel) {
		this.typeValueVOListModel = typeValueVOListModel;
	}

	//--------------------------------------------------------------------
	//--- metodos para atender acciones 							 end()
	//--------------------------------------------------------------------

	//--------------------------------------------------------------------
	//--- getters and setters 										init()
	//--------------------------------------------------------------------
	
	/**
	 * obtencion del servicio valueObjectService
	 */
	public co.gov.medellin.sdep.sisdep.admin.service.IValueObjectService getValueObjectService() {
		return valueObjectService;
	}

	/**
	 * establecimiento del servicio valueObjectService, la inyeccion de la
	 * dependencia la cubre SpringFramework
	 * 
	 * @param valueObjectService
	 */
	public void setValueObjectService(
			co.gov.medellin.sdep.sisdep.admin.service.IValueObjectService valueObjectService) {
		this.valueObjectService = valueObjectService;
	}

	//--------------------------------------------------------------------
	//--- getters and setters 										init()
	//--------------------------------------------------------------------

}
